package com.naiterui.ehp.bs.im.service.message.handler;

import com.naiterui.ehp.bs.im.config.MediaFileConfig;
import com.naiterui.ehp.bs.im.exception.NaiteruiIMException;
import com.naiterui.ehp.bs.im.network.protocl.Media;
import com.naiterui.ehp.bs.im.network.protocl.Message;
import com.naiterui.ehp.bs.im.utils.Constants;
import com.naiterui.ehp.bs.im.utils.ImageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 抽象的消息处理接口
 * 定义了患者端与医生端之间消息发送行为的步骤
 * 无论从患者端 到 医生端
 * 还是从医生端 到 患者端
 * 对消息发送的整体逻辑进行抽象
 * 抽象出具体的步骤并定义成抽象方法
 * 最终由子类实现具体的业务逻辑
 * <P>File name : AbstractMessageHandler.java </P>
 * <P>Author : zhouyanxin </P>
 * <P>Date : 2015年6月27日 </P>
 */
public abstract class AbstractMessageHandler {

    private static Logger LOGGER = LoggerFactory.getLogger(AbstractMessageHandler.class);


    @Autowired
    private MediaFileConfig config;


    /**
     * 处理消息
     * 定义了患者端与医生端之间消息发送行为的步骤
     * 对消息发送的过程进行分割 包含如下几个步骤
     * 1、消息发送前的准备工作
     * 2、持久化消息内容
     * 3、发送消息
     * 4、消息发送完成后的其他逻辑处理
     * 由于患者端 和 医生端的业务逻辑区别，上述4个步骤分别交由具体的子类进行实现
     * AbstractMessageHandler.handleMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年6月27日 </P>
     *
     * @param message
     *
     * @return
     */
    protected abstract Message<?> handleMessage(Message<?> message) throws NaiteruiIMException;

    /**
     * 消息发送前的数据准备工作
     * 由子类定义具体的准备行为
     * AbstractMessageHandler.preparedMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年9月14日 </P>
     *
     * @param message
     */
    protected Message<?> preparedMessage(Message<?> message) throws NaiteruiIMException {
        return message;
    }

    /**
     * 持久化消息
     * AbstractMessageHandler.persistentMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年9月15日 </P>
     *
     * @param message
     *
     * @throws NaiteruiIMException
     */
    protected void persistentMessage(Message<?> message) throws NaiteruiIMException {

        // 多媒体图片消息
        if (message.getType() == Constants.MESSAGE_TYPE_MEDIA_IMG) {

            // 转换为多媒体消息内容对象
            Media media = (Media) message.getContent();

            // 截取掉域名
            String filePath = media.getPath();
            filePath = filePath.replace(config.getImageRewrite(), config.getImageRoot());
            String newPath = filePath.replace(".", "_t.");
            // 切图
            ImageUtils.zoomImage(filePath, newPath);
        }

        // 设置系统消息标识
        this.setSysMsgType(message);
    }

    /**
     * 设置系统消息标识
     * AbstractMessageHandler.setSysMsgType()
     *
     * @param message
     *
     * @throws NaiteruiIMException
     * @Author guoyongxiang
     * @Date 2017年6月21日
     * @since 2.8.0
     */
    private void setSysMsgType(Message<?> message) throws NaiteruiIMException {

        switch (message.getType()) {

            case Constants.MESSAGE_TYPE_TEXT:
                // 文本消息
                // 群发通知属于系统消息
                if (message.getExd() != null && message.getExd().getBatchId() != null) {
                    message.setSysMsgType(Message.SYS_MSG_TYPE_SYSTEM);
                }
                break;

            case Constants.MESSAGE_TYPE_MEDIA_IMG:
                // 图片消息
                break;

            case Constants.MESSAGE_TYPE_MEDIA_AUDIO:
                // 语音消息
                break;

            case Constants.MESSAGE_TYPE_MEDIA_VIDEO:
                // 视频消息
                break;

            case Constants.MESSAGE_TYPE_DRUG:
                // 推药消息
                break;

            case Constants.MESSAGE_TYPE_PAID_CONSULT:
                // 付费通知
                // 属于系统消息
                message.setSysMsgType(Message.SYS_MSG_TYPE_SYSTEM);
                break;

            case Constants.MESSAGE_TYPE_PATEINTS_MEDICAL_RECORD:
                // 病历消息
                break;
            case Constants.MESSAGE_TYPE_DOCTORS_MEDICALRECORD:
                // 医生填写病历消息
                break;
            default:
                LOGGER.error("message setting sysMsgType found unknow message type {}, message is {}", message.getType(), message);
                break;
        }
    }

    /**
     * 发送消息
     * 由子类定义具体的发送行为
     * AbstractMessageHandler.sendMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年9月14日 </P>
     *
     * @param message
     */
    protected abstract void sendMessage(Message<?> message) throws NaiteruiIMException;

    /**
     * 消息发送之后的一些附加操作
     * 由具体的子类负责
     * AbstractMessageHandler.afterSendMessage()<BR>
     * <P>Author : zhouyanxin </P>
     * <P>Date : 2015年9月14日 </P>
     *
     * @param message
     *
     * @throws NaiteruiIMException
     */
    protected abstract void afterSendMessage(Message<?> message) throws NaiteruiIMException;

    /**
     * 消息前置校验
     * AbstractMessageHandler.preValidate()
     *
     * @param messageBean
     *
     * @throws NaiteruiIMException
     * @Author mudou
     * @Date 2017年2月17日
     * @since DBYZ-5075
     */
    public abstract void preValidate(Message<?> messageBean) throws NaiteruiIMException;

}
